/***
 * Based on MochiKit.Async@r1525 <http://mochikit.com/>, (c) 2005 Bob Ippolito.
 *
 * Modifications/adaptations (c) 2009 Univrz.
 */
package com.bigflexlib.async
{
	public class DeferredLock
	{
		private static var nextId:uint = 0;

		public var waiting:Array = [];
		public var locked:Boolean = false;
		public var id:uint;

		public function DeferredLock()
		{
			id = nextId++;
		}

		public function acquire():Deferred
		{
	        var d:Deferred = new Deferred();
	        if (this.locked)
	        {
	            this.waiting.push(d);
	        }
	        else
	        {
	            this.locked = true;
	            d.callback(this);
	        }
	        return d;
		}

		public function release():void {
	        if (!this.locked)
	        {
	            throw TypeError("Tried to release an unlocked DeferredLock");
	        }
	        this.locked = false;
	        if (this.waiting.length > 0)
	        {
	            this.locked = true;
	            this.waiting.shift().callback(this);
	        }
		}

		public function toString():String {
	        var state:String;
	        if (this.locked)
	        {
	            state = 'locked, ' + this.waiting.length + ' waiting';
	        }
	        else
	        {
	            state = 'unlocked';
	        }
	        return 'DeferredLock(' + this.id + ', ' + state + ')';
		}
	}
}
